home *** CD-ROM | disk | FTP | other *** search
- #include <minimal.h>
- #include "screen.h"
-
- /* defines for getting/setting terminal process groups */
- #define TIOCGPGRP (('T'<< 8) | 6)
- #define TIOCSPGRP (('T'<< 8) | 7)
-
- SCREEN thescrn;
-
- #define KEYFD -1 /* file descriptor for the keyboard */
- long pgrp; /* process group for our children */
-
- char *oldbase;
-
- #define INBUFSIZ 1024
-
- int
- main(argc, argv)
- int argc;
- char **argv;
- {
- int i, work;
- long c;
- long s;
- char *shell;
- SCREEN *v, thescrn;
- unsigned char cbuf[INBUFSIZ], *cb;
- long readfds, reads;
- extern char *getenv();
-
- oldbase = (char *)Physbase();
- pgrp = Pgetpid();
- if (argc > 1)
- shell = argv[1];
- else
- shell = getenv("SHELL");
-
- if (!shell) {
- Cconws("Usage: miwm shell\r\n");
- Pterm(2);
- }
-
- Cconws("\033f");
-
- screen[0] = &thescrn;
- screen[0]->base = oldbase;
- init(screen[0]);
- run(screen[0], shell);
- readfds = (1L << screen[0]->fd) | 1;
-
- screen[1] = (SCREEN *)Malloc((long)sizeof(*screen[1]));
- screen[1]->base = oldbase+16000;
- init(screen[1]);
- run(screen[1], shell);
- readfds |= (1L << screen[1]->fd);
-
- /* OK, everything's set up; now let's just loop, reading from the keyboard
- and writing to the current screen, and also checking the screens for
- input
- */
- current = screen[0];
- for(;;) {
- work = 0;
- /* check for screen output */
- reads = readfds;
- Fselect(0, &reads, 0L, 0L);
-
- for (i = 0; i < NUMSCREENS; i++) {
- v = screen[i];
- if (!(reads & (1L << v->fd)))
- continue;
- s = Finstat(v->fd);
- if (s > 0) {
- if (s > INBUFSIZ) s = INBUFSIZ;
- flash_off(v);
- cb = cbuf;
- s = Fread(v->fd, s, cb);
- while (s-- > 0) {
- (*(v->state))(v, *cb++);
- }
- work++;
- }
- else if (s < 0) {
- Cconws("Child exited??\r\n");
- quit(s);
- }
- }
-
- /* check for keyboard input */
- flash_on(current);
- if ((reads & 1) && Finstat(KEYFD)) {
- flash_off(current);
- c = Fgetchar(KEYFD, 0);
- if (c >= ALT_1 && c <= ALT_0) {
- if (c == ALT_1)
- current = screen[0];
- else if (c == ALT_2)
- current = screen[1];
- else if (c == ALT_0)
- quit(0);
- }
- else
- Fputchar(current->fd, c, 0);
- flash_on(current);
- }
- if (!work)
- Syield();
- }
- }
-
- quit(x)
- int x;
- {
- Pkill((int)-pgrp, SIGHUP);
- Pterm(x);
- }
-
- run(v, shell)
- SCREEN *v;
- char *shell;
- {
- long pid;
- long fd;
- int oldtty;
-
- static char pty[] = "U:\\PIPE\\MWM.1";
-
- /* create our handle */
- fd = Fcreate(pty, FA_SYSTEM|FA_HIDDEN);
- if (fd < 0) {
- Cconws("couldn't create ");
- Cconws(pty);
- Cconws("\r\n");
- quit(2);
- }
- v->fd = fd;
-
- /* now create the child's handle */
- fd = Fopen(pty, 2);
-
- oldtty = Fdup(-1);
- if (oldtty < 0) {
- Cconws("couldn't dup control terminal!\r\n");
- quit(2);
- }
- Fforce(-1, fd); /* set up new control terminal */
- Fforce(0, fd);
- Fforce(1, fd);
- Fforce(2, fd);
- pid = Pexec(100, shell, "", 0L); /* spawn child in background */
- Fforce(-1, oldtty);
- Fforce(0, oldtty);
- Fforce(1, oldtty);
- Fforce(2, oldtty);
- if (pid < 0) {
- Cconws("couldn't run ");
- Cconws(shell);
- Cconws("\r\n");
- quit((int)pid);
- }
- v->pid = pid;
- Psetpgrp((int)pid, (int)pgrp); /* set the child's process group */
- Fcntl(fd, &pgrp, TIOCSPGRP); /* set the terminal process group */
- Fclose(fd); /* we won't need this side */
- pty[12]++; /* next pty name */
- return 0;
- }
-
-